//
//
//
//
//
// 启动鼠标事件
import * as THREE from 'three';

const isFunction = obj => obj instanceof Function;

export default function threeMouse() {
    let { camera } = this;

    this.mosePosition = new THREE.Vector2(0, 0);

    this.mesh_on; // 当前鼠标指针上的对象

    this.mesh_Down; // 鼠标按下的对象

    this.raycaster = new THREE.Raycaster(); // 射线拾取器

    this.frame = this.renderer.info.render.frame; // 当前渲染的帧数 ( 鼠标滑动事件 一帧只需要执行费一次即可 )

    // 获取选中对象集合
    this.getSelected = () => {
        if (this.peiGroup.children.length === 0) {
            return null;
        } 
        return this.raycaster.intersectObjects(this.peiGroup.children, false)[0];

    };

    let mousemoveEvent = {}; // 鼠标滑动的事件

    // 拾取方法, 由render 方法调用
    this.pickup = (() => { // 创建一个作用域

        let selMesh; // 拾取对象
        let { renderer, scene, camera } = this;

        return () => {
            selMesh = this.getSelected(); // 获取选中对象
            // 如果没有选中就不往下执行了

            if (selMesh || this.mesh_on) {

                selMesh = Object.assign(selMesh || {}, {  // 将来可能用到的对象
                    renderer,
                    scene,
                    camera,
                    type: mousemoveEvent.type,
                    which: mousemoveEvent.which,
                    offsetX: mousemoveEvent.offsetX,
                    offsetY: mousemoveEvent.offsetY,
                    x: mousemoveEvent.x,
                    y: mousemoveEvent.y
                });

                // 触发滑动事件
                if (selMesh.object && this.mesh_on === selMesh.object) {
                    if (isFunction(selMesh.object.onMousemove)) {
                        selMesh.type = 'mousemove';
                        selMesh.object.onMousemove(selMesh);
                    }
                }

                if (this.mesh_on !== selMesh.object) {

                    // 触发滑入滑出事件
                    if (this.mesh_on && isFunction(this.mesh_on.onMouseleave)) {
                        selMesh.type = 'mouseleave';
                        // selMesh.object = this.mesh_on;
                        this.mesh_on.onMouseleave(selMesh);
                        // selMesh.object = null;
                    }

                    if (selMesh.object && isFunction(selMesh.object.onMouseenter)) {
                        selMesh.type = 'mouseenter';
                        selMesh.object.onMouseenter(selMesh);
                    }
                }
            }// if

            this.mesh_on = (selMesh && selMesh.object) ? selMesh.object : null; // 设置为当前鼠标上的对象

            this.renderer.domElement.style.cursor = (this.mesh_on && this.mesh_on.cursor) || 'auto'; // 鼠标样式

        };

    })();

    // 鼠标滑动 设置鼠标位置
    const mousemove = e => {
        e.preventDefault();
        mousemoveEvent = e;

        if (this.frame !== this.renderer.info.render.frame) { // 一帧只执行一次即可

            this.frame = this.renderer.info.render.frame;

            if (document.pointerLockElement) { // 如果当前有元素 锁住了鼠标
                this.mosePosition.set(0, 0); // 鼠标就指向canvas 的正中心
            } else {
                this.mosePosition.x = (e.offsetX / this.renderer.domElement.offsetWidth) * 2 - 1;
                this.mosePosition.y = -(e.offsetY / this.renderer.domElement.offsetHeight) * 2 + 1;
            }
            this.raycaster.setFromCamera(this.mosePosition, camera); // 设置射线拾取的参数

        }// if 一帧只执行一次的判断
    };

    // 鼠标按下事件
    const mousedown = (() => {

        let selMesh;
        let { renderer, scene, camera } = this;

        return e => {

            selMesh = this.getSelected(); // 获取选中对象

            this.mesh_Down = selMesh && selMesh.object ? selMesh.object : null; // 设置为当前鼠标上的对象

            // 触发鼠标按下事件
            if (selMesh && selMesh.object) {
                if (isFunction(selMesh.object.onMousedown)) {
                    Object.assign(selMesh, {
                        renderer,
                        scene,
                        camera,
                        type: e.type,
                        which: e.which,
                        x: e.x,
                        y: e.y
                    });
                    selMesh.object.onMousedown(selMesh);
                }
            } // if

        };// return

    })();

    // 鼠标弹起事件
    const mouseup = (() => { // 创建一个作用域

        let selMesh; // 选中的对象
        let { renderer, scene, camera } = this;

        return e => {

            selMesh = this.getSelected(); // 获取选中对象

            if (selMesh && selMesh.object) {

                Object.assign(selMesh, {
                    renderer,
                    scene,
                    camera,
                    type: e.type,
                    which: e.which,
                    x: e.x,
                    y: e.y
                });

                // 选中并等于按下时的模型 就触发 点击事件
                if (selMesh.object === this.mesh_Down) {
                    if (isFunction(selMesh.object.onClick)) {
                        selMesh.type = 'click';
                        selMesh.object.onClick(selMesh);
                    }
                }

                if (isFunction(selMesh.object.onMouseup)) {
                    selMesh.object.onMouseup(selMesh);
                }

            } // if
        };// return

    })();

    this.renderer.domElement.removeEventListener('mousemove', mousemove, true); // 鼠标移动监听事件
    this.renderer.domElement.removeEventListener('mousedown', mousedown, true); // 鼠标按下监听事件
    this.renderer.domElement.removeEventListener('mouseup', mouseup, true); // 鼠标弹起监听事件

    this.renderer.domElement.addEventListener('mouseenter', () => { this.isPickup = true; }, true); // 鼠标进入开启拾取
    this.renderer.domElement.addEventListener('mouseleave', () => { this.isPickup = false; }, true); // 鼠标离开停止拾取

    this.renderer.domElement.addEventListener('mousemove', mousemove, true); // 鼠标移动监听事件
    this.renderer.domElement.addEventListener('mousedown', mousedown, true); // 鼠标按下监听事件
    this.renderer.domElement.addEventListener('mouseup', mouseup, true); // 鼠标弹起监听事件
}
